﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Mime
{
    using System;

    /// <summary>Represents a parser that processes lines and provides the parse result upon request.</summary>
    /// <typeparam name="TResult">The type of the result.</typeparam>
    internal interface ILineProcessor<TResult>
    {
        /// <summary>Processes the bytes starting at <paramref name="segment"/>.<see cref="ArraySegment{T}.Offset"/> and
        /// returns the offset of the first unprocessed byte.</summary>
        /// <param name="segment">An array segment containing one or more lines of a message.</param>
        /// <returns>The offset of the first unprocessed byte, or,
        /// <paramref name="segment"/>.<see cref="ArraySegment{T}.Offset"/> +
        /// <paramref name="segment"/>.<see cref="ArraySegment{T}.Count"/> if all bytes have been processed.</returns>
        /// <remarks>
        /// <para>As the name suggests, this method processes a full line of text ("\r\n" sequence + all bytes of the
        /// line just before the next "\r\n" sequence). The caller must ensure that the passed array segment
        /// <b>always</b> starts with a "\r\n" sequence, even the very first line of a body (see
        /// <see cref="EntityProcessor{T}"/> for more information). Implementers must return the index of the next
        /// "\r\n" sequence or <paramref name="segment"/>.<see cref="ArraySegment{T}.Offset"/> +
        /// <paramref name="segment"/>.<see cref="ArraySegment{T}.Count"/> if no "\r\n" has been found.</para>
        /// <para>If <paramref name="segment"/> does not contain a "\r\n" sequence starting at
        /// <paramref name="segment"/>.<see cref="ArraySegment{T}.Offset"/> + X, where X is a <b>positive</b> number, then
        /// implementers may assume that the line is the last one.</para>
        /// </remarks>
        int ProcessFirstLine(ArraySegment<byte> segment);

        /// <summary>Gets the result.</summary>
        /// <exception cref="InvalidOperationException"><see cref="GetResult"/> has been called before (it may only be
        /// called once).</exception>
        TResult GetResult();
    }
}
